home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / icon tools / iconian / sources / doloaddt.e < prev    next >
Text File  |  1996-04-07  |  58KB  |  1,875 lines

  1. /*
  2.     DoLoadDT.m  --  A datatype load, scale, remap and dither routine.
  3. */   
  4. /* $VER:doloaddt 0.88 (7.6.95) */
  5.  
  6. /*
  7.  
  8. THIS SOURCE IS COPYRIGHT 1994,1995 by Chad Randall, mbissaymssiK Software
  9.  
  10. If you wish to include this, or any modified version of this routine in your
  11. own program, you *MUST* credit me somewhere in your program and/or documentation.
  12.  
  13. I am distributing this source mainly for those who wish to learn a thing or two.
  14.  
  15. Please don't rip me off.
  16.  
  17. */
  18.  
  19.  
  20. OPT MODULE
  21.  
  22. OPT PREPROCESS
  23.  
  24. MODULE    'exec/memory','exec/types'
  25. MODULE    'dos/dos'
  26. MODULE    'intuition/intuition','intuition/screens','intuition/gadgetclass','intuition/imageclass'
  27. MODULE    'graphics/rastport','graphics/gfx','graphics/text','graphics/scale','graphics/view',
  28.                 'graphics/gfxbase','graphics/clip','graphics/layers','graphics/modeid'
  29. MODULE    'iffparse','libraries/iffparse'
  30. MODULE    'utility','utility/hooks','utility/tagitem'
  31. MODULE    'datatypes','datatypes/datatypes','datatypes/datatypesclass','datatypes/pictureclass'
  32. MODULE    'mathffp'
  33. MODULE    'gadtools','libraries/gadtools'
  34.  
  35. MODULE    'tools/boopsi'
  36.  
  37. MODULE    'mod/fonts'
  38. MODULE    'mod/bits'
  39. MODULE    'mod/compare'
  40. MODULE    'mod/gadgets'
  41. MODULE    'mod/macros'
  42. MODULE    'mod/pool'
  43. MODULE    'mod/color'
  44. MODULE    'mod/tags'
  45.  
  46. MODULE    'gaugeimage','class/gaugeclass'
  47.  
  48. EXPORT OBJECT sizestruct
  49.     font:LONG
  50.     x:INT
  51.     y:INT
  52.     type:CHAR
  53. ENDOBJECT
  54.  
  55. EXPORT OBJECT statwindow
  56.     scr:PTR TO screen
  57.     centerx:INT
  58.     centery:INT
  59.     textfont:PTR TO textfont
  60.     textattr:PTR TO textattr
  61.     textstyle:LONG
  62.     load_string:LONG
  63.     scale_string:LONG
  64.     histogram_string:LONG
  65.     quant_string:LONG
  66.     render_string:LONG
  67.     cancel_string:LONG
  68.     title_string:LONG
  69.     status_string:LONG
  70. ENDOBJECT
  71.  
  72. EXPORT OBJECT gauge
  73.     rast:PTR TO rastport
  74.     scr:PTR TO screen
  75.     x:INT
  76.     y:INT
  77.     w:INT
  78.     h:INT
  79. ENDOBJECT
  80.  
  81. EXPORT OBJECT imageinfo
  82.     source_w:LONG
  83.     source_h:LONG
  84.     destination_x:LONG
  85.     destination_y:LONG
  86.     destination_w:LONG
  87.     destination_h:LONG
  88.     depth:LONG
  89.     highest_pen:LONG
  90.     statwindowx:LONG
  91.     statwindowy:LONG
  92.     reserved3:LONG
  93.     reserved4:LONG
  94.     reserved5:LONG
  95.     reserved6:LONG
  96.     reserved7:LONG
  97.     reserved8:LONG
  98.     blackpen:LONG
  99.     whitepen:LONG
  100.     greypen:LONG
  101. ENDOBJECT
  102.  
  103. /*OBJECT ditherarray
  104.     p1:CHAR
  105.     p2:CHAR
  106.     p3:CHAR
  107.     p4:CHAR
  108.     p5:CHAR
  109.     p6:CHAR
  110.     p7:CHAR
  111.     p8:CHAR
  112.     p9:CHAR
  113.     p10:CHAR
  114.     p11:CHAR
  115.     p12:CHAR
  116.     dividend:CHAR
  117. ENDOBJECT*/
  118.  
  119. EXPORT ENUM DLDT_CENTER=TAG_USER,            ->Centers image in w/h
  120.                         DLDT_INTEGERSCALE,                ->Does integer scaling routines.    NOT FASTER, but may look better.
  121.                         DLDT_DITHER,                            ->If =true then FS dithering is done
  122.                         DLDT_REMAP,                                ->Use FindColor to remap pens?
  123.                         DLDT_ASPECTX,                            ->x aspect value as in x:y
  124.                         DLDT_ASPECTY,                            ->y aspect value
  125.                         DLDT_SCALE,                                ->Should we scale, or crop? if=false then crop.
  126.                         DLDT_USEASPECT,                        ->Should we use the aspect values, or do 1:1 to 1:1?
  127.                         DLDT_ENLARGE,                            ->NOT IMPLEMENTED YET
  128.                         DLDT_CLEAR,                                ->Clears from x->y, w->h
  129.                         DLDT_GAUGE,                                ->A gauge struct.
  130.                         DLDT_CLIGAUGE,                        ->A ptr to a STRING with an imbedded "%s" code.
  131.                         DLDT_HOOK,                                ->A PROCedure (E!) to call periodically.
  132.                         DLDT_INFO,                                ->A ptr to a imageinfo struct to be filled in.
  133.                         DLDT_BIDIRECTIONAL,                ->NOT IMPLEMENTED
  134.                         DLDT_DIARRAY,                            ->NOT IMPLEMENTED
  135.                         DLDT_HIGHPEN,                            ->Highest pen to use, -1 for all available. (default)
  136.                         DLDT_FILLCMAP,                        -> Use DT cmap, and fill-in given cmap! no faint-hearts!!!
  137.                         DLDT_GREYSCALE,                        -> create greyscale icon
  138.                         DLDT_QUANTIZE,                            -> quantize to x number of colors
  139.                         DLDT_CUSTOMFINDCOLOR,            ->Use custom routine! OUCH
  140.                         DLDT_RENDERHAM,                        -> if =6 then HAM6, if =8 then HAM8, else normal
  141.                         DLDT_HAMTHRESHOLD,                -> specifies when to use base-4 colors
  142.                         DLDT_FULLHAMBASE,
  143.                         DLDT_DISCARDERROR,
  144.                         DLDT_STRETCHTOFIT,
  145.                         DLDT_NORENDER,
  146.                         DLDT_STATWINDOW,
  147.                         DLDT_ACTIVATESTATWINDOW,
  148.                         DLDT_DITHERTYPE,
  149.                         DLDT_QUANTTYPE,
  150.                         DLDT_SHOWSIZE
  151.  
  152. EXPORT ENUM DITH_ERRORDIFF,DITH_FLOYD,DITH_STUCKI,DITH_BURKES
  153. EXPORT ENUM QUANT_VERBATIM,QUANT_POPULARITY,QUANT_MEDIANCUT,QUANT_MEDIANCUT2,QUANT_MEDIANCUT3,QUANT_MEDIANCUT4,QUANT_MEDIANCUT5,QUANT_MEDIANCUT6,QUANT_MEDIANCUT7,QUANT_END
  154. EXPORT ENUM TEXT_NORMAL,TEXT_SHADOW,TEXT_OUTLINE
  155.  
  156. DEF dtlib,utillib,ifflib,mathlib
  157.  
  158.  
  159. #define PPM_GETR(p) (Shr(Shr(((p) AND $FF0000),8),8))
  160. #define PPM_GETG(p) (Shr(((p) AND $FF00),8))
  161. #define PPM_GETB(p) ((p) AND $FF)
  162.  
  163. #define PPM_PUTR(red) (Shl(Shl(((red) AND $FF),8),8))
  164. #define PPM_PUTG(grn) (Shl(((grn) AND $FF),8))
  165. #define PPM_PUTB(blu) ((blu) AND $FF)
  166.  
  167. #define PPM_ASSIGN(red,grn,blu) ((Shl(Shl(red AND $FF,8),8)) OR (Shl(grn AND $FF,8)) OR (blu AND $FF))
  168.  
  169. OBJECT box
  170.     ind:LONG            -> Where the box starts in the histogram
  171.     colors:LONG    -> The number of entries involved (colorcount)
  172.     sum:LONG        -> The number of pixels involved
  173.     redw:INT        -> The red width   (not scaled)  ^3 (volume)
  174.     grnw:INT        -> The green width (not scaled)
  175.     bluw:INT        -> The blue width  (not scaled)
  176.     red0:INT
  177.     grn0:INT
  178.     blu0:INT
  179.     red1:INT
  180.     grn1:INT
  181.     blu1:INT
  182. ENDOBJECT
  183.  
  184. CONST HASH_SIZE=20023
  185. CONST MAXCOLORS=32767
  186. #define HASHPIXEL(p) (Mod(((p) AND $ffffff),HASH_SIZE))
  187.  
  188. OBJECT colorhist_item
  189.     color:LONG
  190.     value:LONG
  191. ENDOBJECT
  192.  
  193. OBJECT colorhist_list_item
  194.     ch:colorhist_item
  195.     next:PTR TO colorhist_list_item
  196. ENDOBJECT
  197.  
  198. DEF statwindow:PTR TO window
  199. DEF gaugeobj
  200. DEF stat:PTR TO statwindow
  201. DEF histopool
  202. DEF drawinfo:PTR TO drawinfo
  203.  
  204. EXPORT PROC doloaddt(source,rast:PTR TO rastport,cmap:PTR TO colormap,x,y,w,h,taglist) HANDLE
  205.     DEF dtf=NIL:PTR TO dtframebox,fri=NIL:PTR TO frameinfo,obj=NIL:PTR TO datatypeheader,gpl=NIL:PTR TO gplayout
  206.     DEF dtrast=NIL:PTR TO rastport
  207.     DEF red[260]:LIST,grn[260]:LIST,blu[260]:LIST
  208.     DEF cregs,bm=NIL:PTR TO bitmap,bmhd=NIL:PTR TO bitmapheader,modeid
  209.     DEF norender=FALSE
  210.     DEF center,intscale=FALSE,dither=TRUE,remap=TRUE,aspectx=1,aspecty=1,scale=TRUE,useaspect=TRUE,enlarge=FALSE,clear=TRUE
  211.     DEF scalex,scaley,scalef
  212.     DEF res,res2
  213.     DEF trast=NIL:PTR TO rastport,tbm=NIL:PTR TO bitmap
  214.     DEF sfixx,sfixy
  215.     DEF ditz=0,dang=0,dumb=0,body
  216.     DEF usehighpen=-1
  217.     DEF fillcmap=FALSE
  218.     DEF cm
  219.     DEF hammode=FALSE,gauge=FALSE:PTR TO gauge,gaugestr=FALSE
  220.     DEF i,t,u,v,z,xpixper=1,ypixper=1,step,stop
  221.     DEF scalarx,scalary,percent,adjustw,adjusth,finalw,finalh,finalx,finaly
  222.     DEF linebuf=0,redbuf=0,grnbuf=0,blubuf=0
  223.     DEF dithermode=DITH_FLOYD
  224.     DEF showsize=0
  225.     DEF stretch=FALSE
  226.     DEF statx=0,staty=0,statw=0,stath=0
  227.     DEF statgad=0
  228.     DEF glist=0,gad
  229.     DEF tmp1=0,tmp2=0,tmp3=0,tmp4=0,tmp5,tmp6,tmp7,tmp8,ttmp1,ttmp2,ttmp3
  230.     DEF lmp4,lmp5,lmp6
  231.     DEF er1,er2,er3,er4
  232.     DEF eg1,eg2,eg3,eg4
  233.     DEF eb1,eb2,eb3,eb4
  234.     DEF sumred=0,sumgrn=0,sumblu=0,num=0
  235.     DEF fc,reddif,grndif,bludif,grabbuf=0
  236.     DEF realred[260]:LIST,realgrn[260]:LIST,realblu[260]:LIST
  237.     DEF vis=0
  238.     DEF iinfo=0:PTR TO imageinfo
  239.     DEF highpen=0
  240.     DEF activatewindow=FALSE
  241.     DEF speed1,speed6,speed7,speed8
  242.     DEF red24=0,grn24=0,blu24=0
  243.     DEF grey=0,quant=256
  244.     DEF hamr,hamg,hamb
  245.     DEF hadr,hadg,hadb
  246.     DEF renderham=0,hamthres=64
  247.     DEF hambase=3
  248.     DEF discard=FALSE
  249.     DEF quantmode=QUANT_MEDIANCUT
  250.     DEF histo
  251.     DEF gaugeclass=0
  252.  
  253.     histo:=0;statwindow:=0;stat:=0
  254.     dtf:=New(600);fri:=New(600);gpl:=New(600)
  255.     dtrast:=New(SIZEOF rastport);InitRastPort(dtrast)
  256.     trast:=New(SIZEOF rastport);CopyMem(dtrast,trast,SIZEOF rastport);trast.layer:=0
  257.     
  258.     IF checklibs()=FALSE THEN Raise("LIB")
  259.     IF taglist
  260.         center:=findtag(taglist,DLDT_CENTER)
  261.         intscale:=findtag(taglist,DLDT_INTEGERSCALE)
  262.         dither:=findtag(taglist,DLDT_DITHER,TRUE)
  263.         remap:=findtag(taglist,DLDT_REMAP,TRUE)
  264.         aspecty:=findtag(taglist,DLDT_ASPECTX,1)
  265.         aspectx:=findtag(taglist,DLDT_ASPECTY,1)
  266.         scale:=findtag(taglist,DLDT_SCALE,TRUE)
  267.         useaspect:=findtag(taglist,DLDT_USEASPECT,TRUE)
  268.         enlarge:=findtag(taglist,DLDT_ENLARGE)
  269.         clear:=findtag(taglist,DLDT_CLEAR,TRUE)
  270.         gauge:=findtag(taglist,DLDT_GAUGE)
  271.         gaugestr:=findtag(taglist,DLDT_CLIGAUGE)
  272.         iinfo:=findtag(taglist,DLDT_INFO)
  273.         usehighpen:=findtag(taglist,DLDT_HIGHPEN,-1)
  274.         fillcmap:=findtag(taglist,DLDT_FILLCMAP)
  275.         quant:=limit(findtag(taglist,DLDT_QUANTIZE,256),1,256)
  276.         grey:=limit(findtag(taglist,DLDT_GREYSCALE),0,2)
  277.         renderham:=limit(findtag(taglist,DLDT_RENDERHAM),0,8)
  278.         hamthres:=limit(findtag(taglist,DLDT_HAMTHRESHOLD,64),0,760)
  279.         speed8:=findtag(taglist,DLDT_FULLHAMBASE)
  280.         IF speed8
  281.             IF renderham=6
  282.                 hambase:=15
  283.             ELSE
  284.                 hambase:=63
  285.             ENDIF
  286.         ENDIF
  287.         discard:=findtag(taglist,DLDT_DISCARDERROR,discard)
  288.         stretch:=findtag(taglist,DLDT_STRETCHTOFIT,stretch)
  289.         norender:=findtag(taglist,DLDT_NORENDER,norender)
  290.         stat:=findtag(taglist,DLDT_STATWINDOW,stat)
  291.         activatewindow:=findtag(taglist,DLDT_ACTIVATESTATWINDOW,activatewindow)
  292.         dithermode:=findtag(taglist,DLDT_DITHERTYPE,dithermode)
  293.         quantmode:=findtag(taglist,DLDT_QUANTTYPE,quantmode)
  294.         showsize:=findtag(taglist,DLDT_SHOWSIZE)
  295.  
  296. ->WriteF('quantmode=\d\n',quantmode)
  297.  
  298.          IF usehighpen=-1 THEN usehighpen:=256
  299.         IF (quant<256)
  300.             usehighpen:=limit(smaller(usehighpen,quant-1),1,255)
  301.         ENDIF
  302.     ENDIF
  303.  
  304.      IF stat
  305.         drawinfo:=GetScreenDrawInfo(stat.scr)
  306.         vis:=GetVisualInfoA(stat.scr, NIL)
  307.     ENDIF
  308.  
  309.      IF (stat AND drawinfo AND vis)
  310.          statw,stath:=biggest(rast,[stat.load_string,stat.scale_string,stat.histogram_string,stat.render_string,TAG_END]:LONG,stat.textfont,stat.textstyle)
  311.          tmp1,tmp2:=fontsize2(rast,stat.cancel_string,stat.textfont,stat.textstyle)
  312.          tmp8,tmp7:=fontsize2(rast,stat.status_string,stat.textfont,stat.textstyle)
  313.          statw:=bigger(bigger(statw,tmp1),tmp8)
  314.         tmp8:=bigger(tmp8,statw)
  315.          statx:=stat.centerx-(statw/2)
  316.          staty:=stat.centery-(stath/2)
  317.          tmp3:=(WFLG_SMART_REFRESH OR WFLG_DRAGBAR OR WFLG_DEPTHGADGET)
  318.          IF activatewindow THEN tmp3:=tmp3 OR WFLG_ACTIVATE
  319.          statwindow:=OpenWindowTagList(0,
  320.                                      [WA_INNERWIDTH,statw+16,
  321.                                         WA_INNERHEIGHT,stath+14+tmp2+tmp7,
  322.                                         WA_LEFT,statx,
  323.                                         WA_TOP,staty,
  324.                                         WA_FLAGS,tmp3,
  325.                                         WA_TITLE,stat.title_string,
  326.                                         WA_CUSTOMSCREEN,stat.scr,
  327.                                         WA_IDCMP,(BUTTONIDCMP OR IDCMP_REFRESHWINDOW),
  328.                                         WA_NEWLOOKMENUS,TRUE,
  329.                                         WA_AUTOADJUST,TRUE,
  330.                                         NIL])
  331.         SetAPen(statwindow.rport,2)
  332.         SetBPen(statwindow.rport,0)
  333.         setafpt(statwindow.rport,[%1010101010101010,%0101010101010101]:INT,1)
  334.         SetDrMd(statwindow.rport,RP_JAM2)
  335.         RectFill(statwindow.rport,statwindow.borderleft,statwindow.bordertop,rightedge(statwindow)-1,bottomedge(statwindow)-1)
  336.         setafpt(statwindow.rport,0,0)
  337.         
  338.         IF statwindow
  339.             gaugeclass:=Init_gaugeiclass()
  340.             gad:=CreateContext({glist})
  341.              tmp3:=(statwindow.width/2)-(tmp1/2)
  342.              tmp4:=(statwindow.height-statwindow.borderbottom-tmp2-3)
  343.             statgad,gad:=CreateGadgetA(BUTTON_KIND,gad,
  344.                                                 [tmp3-8,tmp4,tmp1+16,tmp2+2,stat.cancel_string,stat.textattr,1,0,vis,0]:newgadget,[NIL,NIL])
  345.             AddGList(statwindow,statgad,-1,-1,0)
  346.             RefreshGList(statgad,statwindow,0,-1)
  347.             disablegadget(statgad,statwindow)
  348.  
  349.             gaugeobj:=NewObjectA(gaugeclass,NIL,
  350.                  [IA_LEFT,statwindow.borderleft+2,
  351.                     IA_TOP,statwindow.bordertop+6+tmp7,
  352.                     IA_WIDTH,insidewidth(statwindow)-4,
  353.                     IA_HEIGHT,stath+4,
  354.                     GAUGEIA_TEXTFONT,stat.textfont,
  355.                     GAUGEIA_TEXTSTYLE,stat.textstyle,
  356.                     GAUGEIA_SCREEN,stat.scr,
  357.                     GAUGEIA_STYLE,GAUGETYPE_FANCY,
  358.                     TAG_END])
  359.  
  360.             tmp1:=(statwindow.width/2)-(tmp8/2)
  361.             tmp2:=statwindow.bordertop+2
  362.             drawbevelbox(vis,statwindow.rport,tmp1-6,tmp2,tmp8+12,tmp7+3,1,TRUE,0)
  363.             Move(statwindow.rport,tmp1,stat.textfont.baseline+tmp2+1)
  364.             SetAPen(statwindow.rport,1)
  365.             SetFont(statwindow.rport,stat.textfont)
  366.             Text(statwindow.rport,stat.status_string,StrLen(stat.status_string))
  367.             SetAttrsA(gaugeobj,[IA_DATA,stat.load_string,TAG_END])
  368.             DrawImageState(statwindow.rport,gaugeobj,0,0,IDS_INACTIVENORMAL,drawinfo)
  369.         ENDIF
  370.      ENDIF
  371.  
  372.     IF source<257
  373.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_CLIPBOARD,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  374.     ELSE
  375.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_FILE,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  376.     ENDIF
  377.     IF obj
  378.         IF (drawinfo=0) THEN IF (gauge) THEN drawinfo:=GetScreenDrawInfo(gauge.scr)
  379.         PutLong(dtf,DTM_FRAMEBOX)
  380.         dtf.frameinfo:=fri
  381.         dtf.contentsinfo:=fri
  382.         dtf.sizeframeinfo:=SIZEOF frameinfo
  383.         IF (domethod(obj,dtf))
  384.             PutLong(gpl,DTM_PROCLAYOUT)
  385.             gpl.ginfo:=NIL
  386.             gpl.initial:=1
  387.             IF (domethod(obj,gpl))
  388.                 GetDTAttrsA(obj,[PDTA_CREGS,{cregs},PDTA_BITMAP,{bm},PDTA_BITMAPHEADER,{bmhd},PDTA_MODEID,{modeid},NIL,NIL])
  389.                 IF (modeid AND HAM_KEY);hammode:=TRUE;ENDIF
  390.                 dtrast.bitmap:=bm
  391.                 IF usehighpen=256 THEN usehighpen:=-1
  392.                 IF bm<>NIL
  393.                     body:=cregs
  394.                     FOR i:=0 TO (Shl(1,(bmhd.depth))-1)
  395.                         ditz:=Char(body);body:=body+4;red[i]:=ditz
  396.                         dang:=Char(body);body:=body+4;grn[i]:=dang
  397.                         dumb:=Char(body);body:=body+4;blu[i]:=dumb
  398.                     ENDFOR
  399.                     grabbuf:=New(128)
  400.  
  401.                     tbm:=AllocBitMap((bmhd.width*2),1,8,(BMF_CLEAR OR BMF_STANDARD),NIL)
  402.                     trast.bitmap:=tbm
  403.  
  404.                     adjustw:=SpFlt(bmhd.width)
  405.                     adjusth:=SpFlt(bmhd.height)
  406.                     IF ((useaspect<>FALSE) AND (intscale=FALSE))
  407.                         IF bmhd.xaspect=0 THEN bmhd.xaspect:=1
  408.                         IF bmhd.yaspect=0 THEN bmhd.yaspect:=1
  409.                         scalarx:=SpDiv(SpFlt(aspectx),SpFlt(bmhd.xaspect))
  410.                         scalary:=SpDiv(SpFlt(aspecty),SpFlt(bmhd.yaspect))
  411.  
  412.                         res:=SpCmp(scalarx,scalary)
  413.                         IF res<0    -> scaraly is GREATER THAN scalarx
  414.                             percent:=SpDiv(scalarx,scalary)
  415.                             adjusth:=SpMul(percent,SpFlt(bmhd.height))
  416.                         ELSE
  417.                             percent:=SpDiv(scalary,scalarx)
  418.                             adjustw:=SpMul(percent,SpFlt(bmhd.width))
  419.                         ENDIF
  420.                     ENDIF
  421.  
  422.                     finalx:=x;finaly:=y;finalw:=w;finalh:=h;scalex:=SpFlt(1);scaley:=SpFlt(1)
  423.  
  424.                     res:=SpCmp(SpFlt(w),adjustw)
  425.                     res2:=SpCmp(SpFlt(h),adjusth)
  426.                     IF (((res<0) OR (res2<0)) AND (scale<>FALSE))    -> Datatype is LARGER than workspace, so scale?
  427.                         IF (intscale<>FALSE)
  428.                             scalex:=SpFlt(SpFix( SpDiv(SpFlt(w),SpFlt(SpFix(adjustw)))))
  429.                             scaley:=SpFlt(SpFix( SpDiv(SpFlt(h),SpFlt(SpFix(adjusth)))))
  430.                             res:=SpCmp(scalex,scaley)
  431.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  432.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  433.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  434.                         ELSE
  435.                             scalex:=SpDiv(SpFlt(w),adjustw)
  436.                             scaley:=SpDiv(SpFlt(h),adjusth)
  437.                             res:=SpCmp(scalex,scaley)
  438.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  439.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  440.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  441.                         ENDIF
  442.                         IF (stretch)
  443.                             finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  444. ->                            finalw:=w;finalh:=h
  445.                         ENDIF
  446.                         xpixper:=SpDiv(SpFlt(finalw),SpFlt(bmhd.width))
  447.                         ypixper:=SpDiv(SpFlt(finalh),SpFlt(bmhd.height))
  448.                     ELSE
  449.                         finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  450.                         xpixper:=SpFlt(1);ypixper:=SpFlt(1)
  451.                     ENDIF
  452.  
  453. ->WriteF('\nfinalw=\d\nfinalh=\d\nxpixper=\d\nypixper=\d\n',finalw,finalh,SpFix(xpixper),SpFix(ypixper))
  454.                     
  455.                     IF center
  456.                         finalx:=x+(w/2)-(finalw/2)
  457.                         finaly:=y+(h/2)-(finalh/2)
  458.                     ENDIF
  459.  
  460. ->                    IF statgauge THEN cleargauge(statgauge)
  461.                     IF statgad THEN enablegadget(statgad,statwindow)
  462.  
  463.                     IF ((remap=FALSE) AND (scale=FALSE))
  464.                         FOR t:=0 TO finalh-1
  465.                             IF checkcancel(statwindow) THEN Raise("canc")
  466.                             IF (((t+3)/4) = (t/4))
  467.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.render_string,drawinfo)
  468.                             ENDIF
  469.                             FOR i:=0 TO finalw-1
  470.                                 fc:=ReadPixel(dtrast,i,t)
  471.                                 WHILE fc>usehighpen
  472.                                     fc:=Shr(fc,1)
  473.                                 ENDWHILE
  474.                                 IF highpen<fc THEN highpen:=fc
  475.                                 SetAPen(rast,fc)
  476.                                 WritePixel(rast,finalx+i,finaly+t)
  477.                             ENDFOR
  478.                         ENDFOR
  479.                     ELSE
  480.                         redbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  481.                         grnbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  482.                         blubuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  483.                         linebuf:=New(bmhd.width*8)
  484.  
  485.                         sfixx:=SpFix(xpixper)-1
  486.                         sfixy:=SpFix(ypixper)-1
  487.  
  488.                         red24:=New(finalw*(finalh+16))
  489.                         grn24:=New(finalw*(finalh+16))
  490.                         blu24:=New(finalw*(finalh+16))
  491.  
  492.                         FOR t:=0 TO (finalh-1)
  493.                             IF checkcancel(statwindow) THEN Raise("canc")
  494.                             IF (((t+3)/4) = (t/4))
  495.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.scale_string,drawinfo)
  496.                             ENDIF
  497.  
  498.                             FOR u:=t TO t+SpFix(ypixper)-1
  499.                                 ReadPixelLine8(dtrast,0,SpFix(SpMul(SpFlt(t),ypixper))+(u-t),bmhd.width,linebuf,trast)
  500.                                 speed8:=Char(linebuf)
  501.                                 tmp1:=red[speed8];tmp2:=grn[speed8];tmp3:=blu[speed8]
  502.                                 IF (hammode)
  503.                                     tmp1:=red[0];tmp2:=grn[0];tmp3:=blu[0]
  504.                                     IF bmhd.depth=8    -> HAM8
  505.                                         IF (speed8 AND %11000000)
  506.                                             IF ((speed8 AND %11000000)=%10000000)    -> Modify RED
  507.                                                 tmp1:=Shl((speed8 AND %111111),2);ENDIF
  508.                                             IF ((speed8 AND %11000000)=%01000000)    -> Modify BLUE
  509.                                                 tmp3:=Shl((speed8 AND %111111),2);ENDIF
  510.                                             IF ((speed8 AND %11000000)=%11000000)    -> Modify GRN
  511.                                                 tmp2:=Shl((speed8 AND %111111),2);ENDIF
  512.                                         ELSE
  513.                                             tmp1:=red[(speed8 AND %111111)];tmp2:=grn[(speed8 AND %111111)];tmp3:=blu[(speed8 AND %111111)]
  514.                                         ENDIF
  515.                                     ELSE
  516.                                         IF (speed8 AND %110000)
  517.                                             IF (speed8 AND %110000)=%100000    -> Modify RED
  518.                                                 tmp1:=Shl((speed8 AND %1111),4);ENDIF
  519.                                             IF (speed8 AND %110000)=%010000    -> Modify BLUE
  520.                                                 tmp3:=Shl((speed8 AND %1111),4);ENDIF
  521.                                             IF (speed8 AND %110000)=%110000    -> Modify GRN
  522.                                                 tmp2:=Shl((speed8 AND %1111),4);ENDIF
  523.                                         ELSE
  524.                                             tmp1:=red[(z AND %1111)];tmp2:=grn[(z AND %1111)];tmp3:=blu[(z AND %1111)]
  525.                                         ENDIF
  526.                                     ENDIF
  527.                                 ENDIF
  528.                                 speed1:=bmhd.width*(u-t)
  529.                                 ditz:=redbuf+speed1
  530.                                 dang:=grnbuf+speed1
  531.                                 dumb:=blubuf+speed1
  532.                                 IF (remap=FALSE) THEN ditz:=redbuf
  533.                                 FOR v:=1 TO bmhd.width
  534.                                     IF (remap=FALSE)
  535.                                         PutChar(ditz,Char(linebuf+v));ditz:=ditz+1
  536.                                     ELSE
  537.  
  538. /*                                        MOVE.L    tmp1,D0
  539.                                         MOVE.L    tmp2,D1
  540.                                         MOVE.L    tmp3,D2
  541.  
  542.                                         LEA            ditz,A1
  543.                                         MOVE.L    (A1),A0
  544.                                         MOVE.B    D0,(A0)+
  545.                                         MOVE.L    A0,(A1)
  546.  
  547.                                         LEA            dang,A1
  548.                                         MOVE.L    (A1),A0
  549.                                         MOVE.B    D1,(A0)+
  550.                                         MOVE.L    A0,(A1)
  551.  
  552.                                         LEA            dumb,A1
  553.                                         MOVE.L    (A1),A0
  554.                                         MOVE.B    D2,(A0)+
  555.                                         MOVE.L    A0,(A1)
  556. */
  557. ->/*
  558.                                         PutChar(ditz,tmp1);ditz:=ditz+1
  559.                                         PutChar(dang,tmp2);dang:=dang+1
  560.                                         PutChar(dumb,tmp3);dumb:=dumb+1
  561. ->*/
  562. /*
  563.                                         MOVE.L    linebuf,A0
  564.                                         MOVE.L    v,D0
  565.                                         SUB.L        D1,D1
  566.                                         MOVE.B    0(A0,D0),D1
  567.                                         MOVE.L    D1,z
  568. */
  569.                                         z:=Char(linebuf+v)
  570.  
  571.                                         IF (hammode=FALSE)
  572.                                             tmp1:=red[z];tmp2:=grn[z];tmp3:=blu[z]
  573.                                         ELSE
  574.                                             IF (bmhd.depth=8)    -> HAM8
  575.                                                 speed7:=(z AND %11000000)
  576.                                                 IF (speed7)
  577.                                                     IF (speed7=%10000000)    -> Modify RED
  578.                                                         tmp1:=Shl((z AND %111111),2)
  579.                                                     ELSE
  580.                                                         IF (speed7=%01000000)
  581.                                                             tmp3:=Shl((z AND %111111),2)
  582.                                                         ELSE
  583.                                                             tmp2:=Shl((z AND %111111),2)
  584.                                                         ENDIF
  585.                                                     ENDIF
  586.                                                 ELSE
  587.                                                     speed6:=(z AND %111111)
  588.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  589.                                                 ENDIF
  590.                                             ELSE
  591.                                                 IF (z AND %110000)
  592.                                                     IF (z AND %110000)=%100000    -> Modify RED
  593.                                                         tmp1:=Shl((z AND %1111),4);ENDIF
  594.                                                     IF (z AND %110000)=%010000    -> Modify BLUE
  595.                                                         tmp3:=Shl((z AND %1111),4);ENDIF
  596.                                                     IF (z AND %110000)=%110000    -> Modify GRN
  597.                                                         tmp2:=Shl((z AND %1111),4);ENDIF
  598.                                                 ELSE
  599.                                                     speed6:=(z AND %1111)
  600.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  601.                                                 ENDIF
  602.                                             ENDIF
  603.                                         ENDIF
  604.                                     ENDIF
  605.                                 ENDFOR
  606.                             ENDFOR
  607.                             IF (remap=FALSE)
  608.                                 FOR i:=0 TO finalw-1
  609.                                     fc:=Char(redbuf+(SpFix(SpMul(xpixper,SpFlt(i)))))
  610.                                     SetAPen(rast,fc)
  611.                                     highpen:=bigger(highpen,fc)
  612.                                      WritePixel(rast,finalx+i,finaly+t)
  613.                                  ENDFOR
  614.                             ELSE
  615.                                 FOR i:=0 TO finalw-1
  616.                                     tmp4:=(SpFix(SpMul(xpixper,SpFlt(i))))
  617.                                     ditz:=redbuf+tmp4
  618.                                     dang:=grnbuf+tmp4
  619.                                     dumb:=blubuf+tmp4
  620.                                     IF ((sfixy>=1) AND (sfixx>=1))
  621.                                         num:=0;sumred:=0;sumgrn:=0;sumblu:=0
  622.                                         MOVEM.L    D0-D7/A0-A3,-(A7)
  623.                                          MOVE.L    ditz,A0
  624.                                          MOVE.L    dang,A1
  625.                                         MOVE.L    dumb,A2
  626.                                         MOVE.L    bmhd,A3
  627.                                         CLR.L        D2        -> The result from Char()
  628.                                         CLR.L        D4        -> num
  629.                                         CLR.L        D5        -> sumred
  630.                                         CLR.L        D6        -> sumgrn
  631.                                         CLR.L        D7        -> sumblu
  632.                                         MOVE.L    sfixy,D0
  633. ->                                        ADD.L        #1,D0
  634. loop3:
  635.                                         MOVE.L    sfixx,D1
  636. ->                                         ADD.L        #1,D1
  637. loop2:
  638.                                         SUB.L        D3,D3                -> EQ: CLR.L    D3 ? Is it faster??!?
  639.                                         MOVE.W    0(A3),D3
  640.                                         MULU        D0,D3
  641.                                         ADD.L        D1,D3
  642.                                         MOVE.B    0(A0,D3),D2
  643.                                         ADD.L        D2,D5
  644.                                         MOVE.B    0(A1,D3),D2
  645.                                         ADD.L        D2,D6
  646.                                         MOVE.B    0(A2,D3),D2
  647.                                         ADD.L        D2,D7
  648.                                         ADDQ.L    #1,D4
  649.                                         DBRA        D1,loop2
  650.                                         DBRA        D0,loop3
  651.                                         MOVE.L    D4,num
  652.                                         MOVE.L    D5,sumred
  653.                                         MOVE.L    D6,sumgrn
  654.                                         MOVE.L    D7,sumblu
  655.                                         MOVEM.L    (A7)+,D0-D7/A0-A3
  656.                                         IF num>0
  657.                                              sumred:=limit(sumred/num,0,255)
  658.                                              sumgrn:=limit(sumgrn/num,0,255)
  659.                                              sumblu:=limit(sumblu/num,0,255)
  660.                                         ENDIF
  661.                                     ELSE
  662.                                          sumred:=Char(ditz)
  663.                                          sumgrn:=Char(dang)
  664.                                          sumblu:=Char(dumb)
  665.                                     ENDIF
  666.                                     MOVE.L    t,D1
  667.                                     MOVE.L    finalw,D2
  668.                                     MULU        D2,D1
  669.                                     ADD.L        i,D1
  670.  
  671.                                     MOVE.L    D1,D0
  672.                                     ADD.L        red24,D0
  673.                                     MOVE.L    D0,A0
  674.                                     MOVE.L    sumred,D2
  675.                                     MOVE.B    D2,(A0)
  676.                                     
  677.                                     MOVE.L    D1,D0
  678.                                     ADD.L        grn24,D0
  679.                                     MOVE.L    D0,A0
  680.                                     MOVE.L    sumgrn,D2
  681.                                     MOVE.B    D2,(A0)
  682.                                     
  683.                                     MOVE.L    D1,D0
  684.                                     ADD.L        blu24,D0
  685.                                     MOVE.L    D0,A0
  686.                                     MOVE.L    sumblu,D2
  687.                                     MOVE.B    D2,(A0)
  688.                                     
  689.                                 ENDFOR
  690.                             ENDIF
  691.                         ENDFOR
  692.                         IF showsize THEN mergesize(showsize,bmhd.width,bmhd.height,red24,grn24,blu24,finalw,finalh)
  693.                         IF grey
  694.                             tmp1:=red24
  695.                             tmp2:=grn24
  696.                             tmp3:=blu24
  697.                             tmp7:=finalh*finalw-1
  698.                             FOR i:=0 TO tmp7
  699.                                 IF grey=1
  700.                                     er1:=(Char(tmp1)*1000)/30
  701.                                     er2:=(Char(tmp2)*1000)/30
  702.                                     er3:=(Char(tmp3)*1000)/30
  703.                                 ELSE
  704.                                     er1:=(Char(tmp1)*3000)/100
  705.                                     er2:=(Char(tmp2)*6000)/100
  706.                                     er3:=(Char(tmp3)*1000)/100
  707.                                 ENDIF
  708.                                 er4:=(er1+er2+er3)/100
  709.                                 PutChar(tmp1,er4)
  710.                                 PutChar(tmp2,er4)
  711.                                 PutChar(tmp3,er4)
  712.                                 tmp1:=tmp1+1
  713.                                 tmp2:=tmp2+1
  714.                                 tmp3:=tmp3+1
  715.                             ENDFOR
  716.                         ENDIF
  717.  
  718.                         IF (fillcmap)
  719.                             IF usehighpen>=quant THEN usehighpen:=(quant-1)
  720.                             SELECT QUANT_END OF quantmode
  721.                             CASE QUANT_VERBATIM
  722.                                 FOR i:=0 TO quant
  723.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(red[i]),byte2long(grn[i]),byte2long(blu[i]))
  724.                                 ENDFOR
  725.                             CASE QUANT_POPULARITY
  726.                                 histo:=New(20000)
  727.                                 FOR t:=0 TO finalh-1
  728.                                     IF checkcancel(statwindow) THEN Raise("canc")
  729.                                         IF ((t/4)=((t+3)/4))
  730.                                             IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.histogram_string,drawinfo)
  731.                                         ENDIF
  732.                                     FOR i:=0 TO finalw-1
  733.                                         tmp1:=Shr((Char(red24+(t*finalw)+i) AND $F0) ,4)
  734.                                         tmp2:=Shr((Char(grn24+(t*finalw)+i) AND $F0) ,4)
  735.                                         tmp3:=Shr((Char(blu24+(t*finalw)+i) AND $F0) ,4)
  736.                                         tmp4:=histo+((tmp1+(tmp2*16)+(tmp3*256))*4)
  737.                                         PutLong(tmp4,(Long(tmp4)+1))
  738.                                     ENDFOR
  739.                                 ENDFOR
  740.                                 FOR i:=0 TO quant
  741.                                     IF checkcancel(statwindow) THEN Raise("canc")
  742.                                         IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,i,quant,stat.quant_string,drawinfo)
  743.                                     tmp1:=0
  744.                                     tmp2:=0
  745.                                     tmp3:=histo
  746.                                     FOR t:=0 TO 4095
  747.                                         IF Long(tmp3)>tmp2
  748.                                             tmp2:=Long(tmp3)
  749.                                             tmp1:=t
  750.                                         ENDIF
  751.                                         tmp3:=tmp3+4
  752.                                     ENDFOR
  753.                                     PutLong(histo+(tmp1*4),0)
  754.                                     er1:=tmp1 AND $F
  755.                                     er1:=er1 OR Shl(er1,4)
  756.                                     er2:=Shr((tmp1 AND $F0),4)
  757.                                     er2:=er2 OR Shl(er2,4)
  758.                                     er3:=Shr((tmp1 AND $F00),8)
  759.                                     er3:=er3 OR Shl(er3,4)
  760.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(er1),byte2long(er2),byte2long(er3))
  761.                                 ENDFOR
  762.                             DEFAULT
  763.                                 cm:=domediancut(red24,grn24,blu24,finalw,finalh,cmap,quant,quantmode)
  764.                                 IF (cm)
  765.                                     FOR i:=0 TO (quant)
  766.                                         SetRGB32CM(cmap,smaller(i,255),byte2long(PPM_GETR(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETG(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETB(Long(cm+(i*SIZEOF colorhist_item)))))
  767.                                     ENDFOR
  768.                                     Dispose(cm)
  769.                                 ENDIF
  770.                             ENDSELECT
  771.                             IF ((quant>4) AND (quantmode<>QUANT_VERBATIM))
  772.                                 doexchange(cmap,3,0,255,255,usehighpen)
  773.                                 doexchange(cmap,2,255,255,255,usehighpen)
  774.                                 doexchange(cmap,1,0,0,0,usehighpen)
  775.                                 doexchange(cmap,0,128,128,128,usehighpen)
  776.                                 REPEAT
  777.                                     tmp1:=0
  778.                                     FOR i:=4 TO (quant-1)
  779.                                         GetRGB32(cmap,i,2,grabbuf)
  780.                                         IF ((Char(grabbuf)+Char(grabbuf+4)+Char(grabbuf+8))<(Char(grabbuf+12)+Char(grabbuf+16)+Char(grabbuf+20)))
  781.                                             SetRGB32CM(cmap,smaller(i+1,255),byte2long(Char(grabbuf)),byte2long(Char(grabbuf+4)),byte2long(Char(grabbuf+8)))
  782.                                             SetRGB32CM(cmap,smaller(i,255),byte2long(Char(grabbuf+12)),byte2long(Char(grabbuf+16)),byte2long(Char(grabbuf+20)))
  783.                                             tmp1:=1
  784.                                         ENDIF
  785.                                     ENDFOR
  786.                                 UNTIL tmp1=0
  787.                             ENDIF
  788.                         ENDIF
  789.                         IF (norender) THEN Raise("nore")
  790.                         IF (clear<>FALSE);SetAPen(rast,0);RectFill(rast,x,y,x+w-1,y+h-1);ENDIF
  791.                         FOR i:=0 TO Shl(1,8)-1
  792.                             GetRGB32(cmap,i,1,grabbuf)
  793.                             realred[i]:=Char(grabbuf)
  794.                             realgrn[i]:=Char(grabbuf+4)
  795.                             realblu[i]:=Char(grabbuf+8)
  796.                         ENDFOR
  797.                         IF renderham THEN dither:=FALSE
  798. ->WriteF('\nfinalw=\d\nfinalh=\d\nxpixper=\d\nypixper=\d\n',finalw,finalh,SpFix(xpixper),SpFix(ypixper))
  799.                         FOR t:=0 TO finalh-1
  800.                             IF checkcancel(statwindow) THEN Raise("canc")
  801.                             IF (((t+3)/4)=(t/4))
  802.                                 IF ((gauge<>0) AND (drawinfo<>0))
  803.                                     IF (gauge.rast<>0)
  804.                                         SetAPen(gauge.rast,drawinfo.pens[FILLPEN])
  805.                                         RectFill(gauge.rast,gauge.x,gauge.y,gauge.x+((((gauge.w-2)*100)/(10000/(bigger((t*100/(finalh-1)),1))))),gauge.y+gauge.h-1)
  806.                                     ENDIF
  807.                                 ENDIF
  808.                                 IF (gaugestr<>0)
  809.                                     WriteF(gaugestr,smaller(((t*100))/(bigger(finalh-1,1)),100))
  810.                                 ENDIF
  811.                                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,t,finalh-1,stat.render_string,drawinfo)
  812.                             ENDIF
  813.  
  814.                             IF ((((t+1)/2)=(t/2)) OR (renderham>5) OR (dithermode=DITH_ERRORDIFF))
  815.                                 i:=0;stop:=finalw;step:=1
  816.                                 tmp4:=t*finalw
  817.                                 tmp1:=red24+tmp4
  818.                                 tmp2:=grn24+tmp4
  819.                                 tmp3:=blu24+tmp4
  820.                             ELSE
  821.                                 i:=finalw-1;stop:=-1;step:=-1
  822.                                 tmp4:=(t*finalw)+(finalw-1)
  823.                                 tmp1:=red24+tmp4
  824.                                 tmp2:=grn24+tmp4
  825.                                 tmp3:=blu24+tmp4
  826.                             ENDIF
  827.                             REPEAT
  828.                                 tmp4:=Char(tmp1)
  829.                                 tmp5:=Char(tmp2)
  830.                                 tmp6:=Char(tmp3)
  831.                                 lmp4:=byte2long(tmp4)
  832.                                 lmp5:=byte2long(tmp5)
  833.                                 lmp6:=byte2long(tmp6)
  834.                                 IF (dither=FALSE)
  835.                                     SELECT 9 OF renderham
  836.                                     CASE 6,8
  837.                                         IF (i>0)
  838.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  839.                                             hadr:=Abs(tmp4-realred[fc])
  840.                                             hadg:=Abs(tmp5-realgrn[fc])
  841.                                             hadb:=Abs(tmp6-realblu[fc])
  842.                                             IF ((hadr+hadg+hadb)<=hamthres)
  843.                                                 hamr:=realred[fc]            -> CHAR
  844.                                                 hamg:=realgrn[fc]
  845.                                                 hamb:=realblu[fc]
  846.                                             ELSE
  847.                                                 hadr:=Abs(tmp4-hamr)    -> CHAR-CHAR
  848.                                                 hadg:=Abs(tmp5-hamg)
  849.                                                 hadb:=Abs(tmp6-hamb)
  850.                                                 IF (renderham=8)
  851.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  852.                                                         hamb:=(tmp6 AND %11111100)
  853.                                                         fc:=(%01000000 OR Shr(hamb,2))
  854.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  855.                                                     ELSE
  856.                                                         IF (hadr>(hadg*2))
  857.                                                             hamr:=(tmp4 AND %11111100)
  858.                                                             fc:=(%10000000 OR Shr(hamr,2))
  859.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  860.                                                         ELSE
  861.                                                             hamg:=(tmp5 AND %11111100)
  862.                                                             fc:=(%11000000 OR Shr(hamg,2))
  863.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  864.                                                         ENDIF
  865.                                                     ENDIF
  866.                                                 ELSE
  867.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  868.                                                         hamb:=(tmp6 AND %11110000)
  869.                                                         fc:=(%010000 OR Shr(hamb,4))
  870.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  871.                                                     ELSE
  872.                                                         IF (hadr>(hadg*2))
  873.                                                             hamr:=(tmp4 AND %11110000)
  874.                                                             fc:=(%100000 OR Shr(hamr,4))
  875.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  876.                                                         ELSE
  877.                                                             hamg:=(tmp5 AND %11110000)
  878.                                                             fc:=(%110000 OR Shr(hamg,4))
  879.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  880.                                                         ENDIF
  881.                                                     ENDIF
  882.                                                 ENDIF
  883.                                             ENDIF
  884.                                         ELSE
  885.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  886.                                             hamr:=realred[fc]
  887.                                             hamg:=realgrn[fc]
  888.                                             hamb:=realblu[fc]
  889.                                         ENDIF
  890.                                     DEFAULT
  891.                                         fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  892.                                     ENDSELECT
  893.                                     IF fc>highpen THEN highpen:=fc
  894.                                     SetAPen(rast,fc)
  895.                                     WritePixel(rast,finalx+i,finaly+t)
  896.                                 ELSE                                                                                -> Do dither!
  897.                                     fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  898.                                     IF fc>highpen THEN highpen:=fc
  899.                                     SetAPen(rast,fc)
  900.                                     WritePixel(rast,finalx+i,finaly+t)
  901.                          reddif:=tmp4-realred[fc]
  902.                        grndif:=tmp5-realgrn[fc]
  903.                        bludif:=tmp6-realblu[fc]
  904.                        SELECT 4 OF dithermode
  905.                        CASE DITH_FLOYD,DITH_ERRORDIFF
  906.                            IF dithermode=DITH_FLOYD
  907.                                er1:=(reddif*7)/16
  908.                                er2:=(reddif*3)/16
  909.                                er3:=(reddif*5)/16
  910.                                er4:=reddif-er1-er2-er3
  911.                                eg1:=(grndif*7)/16
  912.                                eg2:=(grndif*3)/16
  913.                                eg3:=(grndif*5)/16
  914.                                eg4:=grndif-eg1-eg2-eg3
  915.                                eb1:=(bludif*7)/16
  916.                                eb2:=(bludif*3)/16
  917.                                eb3:=(bludif*5)/16
  918.                                eb4:=bludif-eb1-eb2-eb3
  919.                            ELSE
  920.                                er1:=(reddif*3)/8 AND %11111111111111111111111111111110
  921.                                er2:=0
  922.                                er3:=er1
  923.                                er4:=reddif-er1-er3 AND %11111111111111111111111111111100
  924.                                eg1:=(grndif*3)/8 AND %11111111111111111111111111111100
  925.                                eg2:=0
  926.                                eg3:=eg1
  927.                                eg4:=grndif-eg1-eg3 AND %11111111111111111111111111111100
  928.                                eb1:=(bludif*3)/8 AND  %11111111111111111111111111111110
  929.                                eb2:=0
  930.                                eb3:=eb1
  931.                                eb4:=bludif-eb1-eb3 AND %11111111111111111111111111111100
  932.                              ENDIF
  933.                            IF step=1
  934.                                IF ((i+1)<stop)
  935.                                                 byteplace(tmp1+1,er1)
  936.                                                 byteplace(tmp2+1,eg1)
  937.                                                 byteplace(tmp3+1,eb1)
  938.                                             ENDIF
  939.                                IF t<(finalh-1)
  940.                                      IF ((i+1)<stop)
  941.                                          byteplace(tmp1+1+finalw,er4)
  942.                                          byteplace(tmp2+1+finalw,eg4)
  943.                                          byteplace(tmp3+1+finalw,eb4)
  944.                                      ENDIF
  945.                                      IF (i>0)
  946.                                                     byteplace(tmp1-1+finalw,er2)
  947.                                                     byteplace(tmp2-1+finalw,eg2)
  948.                                                     byteplace(tmp3-1+finalw,eb2)
  949.                                                 ENDIF
  950.                                      byteplace(tmp1+finalw,er3)
  951.                                      byteplace(tmp2+finalw,eg3)
  952.                                      byteplace(tmp3+finalw,eb3)
  953.                                  ENDIF
  954.                            ELSE
  955.                                IF ((i-1)>stop)
  956.                                    byteplace(tmp1-1,er1)
  957.                                    byteplace(tmp2-1,eg1)
  958.                                    byteplace(tmp3-1,eb1)
  959.                                ENDIF
  960.                                IF t<(finalh-1)
  961.                                      IF ((i-1)>stop)
  962.                                          byteplace(tmp1-1+finalw,er4)
  963.                                          byteplace(tmp2-1+finalw,eg4)
  964.                                          byteplace(tmp3-1+finalw,eb4)
  965.                                      ENDIF
  966.                                      IF (i<(finalw-1))
  967.                                          byteplace(tmp1+1+finalw,er2)
  968.                                          byteplace(tmp2+1+finalw,eg2)
  969.                                          byteplace(tmp3+1+finalw,eb2)
  970.                                      ENDIF
  971.                                      byteplace(tmp1+finalw,er3)
  972.                                      byteplace(tmp2+finalw,eg3)
  973.                                      byteplace(tmp3+finalw,eb3)
  974.                                  ENDIF
  975.                            ENDIF
  976.                        CASE DITH_BURKES,DITH_STUCKI
  977.                            IF dithermode=DITH_BURKES
  978.                                er1:=(reddif*8)/32                                ->8
  979.                                er2:=(reddif*4)/32                                ->4
  980.                                er3:=(reddif-(er1*2)-(er2*3))/2        ->2
  981.                                eg1:=(grndif*8)/32
  982.                                eg2:=(grndif*4)/32
  983.                                eg3:=(grndif-(eg1*2)-(eg2*3))/2
  984.                                eb1:=(bludif*8)/32
  985.                                eb2:=(bludif*4)/32
  986.                                eb3:=(bludif-(eb1*2)-(eb2*3))/2
  987.                              ELSE
  988.                                er1:=(reddif*8)/42                                ->8
  989.                                er2:=(reddif*4)/42                                ->4
  990.                                er3:=(reddif*2)/42                                ->2
  991.                                er4:=(reddif-(er1*2)-(er2*4)-(er3*4))/2        ->1
  992.                                eg1:=(grndif*8)/42
  993.                                eg2:=(grndif*4)/42
  994.                                eg3:=(grndif*2)/42
  995.                                eg4:=(grndif-(eg1*2)-(eg2*4)-(eg3*4))/2
  996.                                eb1:=(bludif*8)/42
  997.                                eb2:=(bludif*4)/42
  998.                                eb3:=(bludif*2)/42
  999.                                eb4:=(bludif-(eb1*2)-(eb2*4)-(eb3*4))/2
  1000.                              ENDIF
  1001.                            IF step=1
  1002.                                IF ((i+1)<stop)
  1003.                                                 byteplace(tmp1+1,er1)
  1004.                                                 byteplace(tmp2+1,eg1)
  1005.                                                 byteplace(tmp3+1,eb1)
  1006.                                                 IF ((i+2)<stop)
  1007.                                                     byteplace(tmp1+2,er2)
  1008.                                                     byteplace(tmp2+2,eg2)
  1009.                                                     byteplace(tmp3+2,eb2)
  1010.                                                 ENDIF
  1011.                                             ENDIF
  1012.                                IF t<(finalh-1)
  1013.                                    ttmp1:=tmp1+finalw
  1014.                                    ttmp2:=tmp2+finalw
  1015.                                    ttmp3:=tmp3+finalw
  1016.                                      IF ((i+1)<stop)
  1017.                                          byteplace(ttmp1+1,er2)
  1018.                                          byteplace(ttmp2+1,eg2)
  1019.                                          byteplace(ttmp3+1,eb2)
  1020.                                                     IF ((i+2)<stop)
  1021.                                                         byteplace(ttmp1+2,er3)
  1022.                                                         byteplace(ttmp2+2,eg3)
  1023.                                                         byteplace(ttmp3+2,eb3)
  1024.                                                     ENDIF
  1025.                                      ENDIF
  1026.                                      IF (i>0)
  1027.                                                     byteplace(ttmp1-1,er2)
  1028.                                                     byteplace(ttmp2-1,eg2)
  1029.                                                     byteplace(ttmp3-1,eb2)
  1030.                                          IF (i>1)
  1031.                                                         byteplace(ttmp1-2,er3)
  1032.                                                         byteplace(ttmp2-2,eg3)
  1033.                                                         byteplace(ttmp3-2,eb3)
  1034.                                          ENDIF
  1035.                                                 ENDIF
  1036.                                      byteplace(ttmp1,er1)
  1037.                                      byteplace(ttmp2,eg1)
  1038.                                      byteplace(ttmp3,eb1)
  1039.                                      IF dithermode=DITH_STUCKI
  1040.                                        IF t<(finalh-1)
  1041.                                            ttmp1:=ttmp1+finalw
  1042.                                            ttmp2:=ttmp2+finalw
  1043.                                            ttmp3:=ttmp3+finalw
  1044.                                              IF ((i+1)<stop)
  1045.                                                  byteplace(ttmp1+1,er3)
  1046.                                                  byteplace(ttmp2+1,eg3)
  1047.                                                  byteplace(ttmp3+1,eb3)
  1048.                                                             IF ((i+2)<stop)
  1049.                                                                 byteplace(ttmp1+2,er4)
  1050.                                                                 byteplace(ttmp2+2,eg4)
  1051.                                                                 byteplace(ttmp3+2,eb4)
  1052.                                                             ENDIF
  1053.                                              ENDIF
  1054.                                              IF (i>0)
  1055.                                                             byteplace(ttmp1-1,er3)
  1056.                                                             byteplace(ttmp2-1,eg3)
  1057.                                                             byteplace(ttmp3-1,eb3)
  1058.                                                  IF (i>1)
  1059.                                                                 byteplace(ttmp1-2,er4)
  1060.                                                                 byteplace(ttmp2-2,eg4)
  1061.                                                                 byteplace(ttmp3-2,eb4)
  1062.                                                  ENDIF
  1063.                                                         ENDIF
  1064.                                              byteplace(ttmp1,er2)
  1065.                                              byteplace(ttmp2,eg2)
  1066.                                              byteplace(ttmp3,eb2)
  1067.                                          ENDIF
  1068.                                      ENDIF
  1069.                                  ENDIF
  1070.                            ELSE
  1071.                                IF ((i-1)>stop)
  1072.                                                 byteplace(tmp1-1,er1)
  1073.                                                 byteplace(tmp2-1,eg1)
  1074.                                                 byteplace(tmp3-1,eb1)
  1075.                                                 IF ((i-2)>stop)
  1076.                                                     byteplace(tmp1-2,er2)
  1077.                                                     byteplace(tmp2-2,eg2)
  1078.                                                     byteplace(tmp3-2,eb2)
  1079.                                                 ENDIF
  1080.                                             ENDIF
  1081.                                IF t<(finalh-1)
  1082.                                    ttmp1:=tmp1+finalw
  1083.                                    ttmp2:=tmp2+finalw
  1084.                                    ttmp3:=tmp3+finalw
  1085.                                      IF ((i-1)>stop)
  1086.                                          byteplace(ttmp1-1,er2)
  1087.                                          byteplace(ttmp2-1,eg2)
  1088.                                          byteplace(ttmp3-1,eb2)
  1089.                                                     IF ((i-2)>stop)
  1090.                                                         byteplace(ttmp1-2,er3)
  1091.                                                         byteplace(ttmp2-2,eg3)
  1092.                                                         byteplace(ttmp3-2,eb3)
  1093.                                                     ENDIF
  1094.                                      ENDIF
  1095.                                      IF (i<(finalw-1))
  1096.                                                     byteplace(ttmp1+1,er2)
  1097.                                                     byteplace(ttmp2+1,eg2)
  1098.                                                     byteplace(ttmp3+1,eb2)
  1099.                                          IF (i<(finalw-2))
  1100.                                                         byteplace(ttmp1+2,er3)
  1101.                                                         byteplace(ttmp2+2,eg3)
  1102.                                                         byteplace(ttmp3+2,eb3)
  1103.                                          ENDIF
  1104.                                                 ENDIF
  1105.                                      byteplace(ttmp1,er1)
  1106.                                      byteplace(ttmp2,eg1)
  1107.                                      byteplace(ttmp3,eb1)
  1108.                                      IF dithermode=DITH_STUCKI
  1109.                                        IF (t<(finalh-1))
  1110.                                            ttmp1:=ttmp1+finalw
  1111.                                            ttmp2:=ttmp2+finalw
  1112.                                            ttmp3:=ttmp3+finalw
  1113.                                              IF ((i-1)>stop)
  1114.                                                  byteplace(ttmp1-1,er3)
  1115.                                                  byteplace(ttmp2-1,eg3)
  1116.                                                  byteplace(ttmp3-1,eb3)
  1117.                                                             IF ((i-2)>stop)
  1118.                                                                 byteplace(ttmp1-2,er4)
  1119.                                                                 byteplace(ttmp2-2,eg4)
  1120.                                                                 byteplace(ttmp3-2,eb4)
  1121.                                                             ENDIF
  1122.                                              ENDIF
  1123.                                              IF (i<(finalw-1))
  1124.                                                             byteplace(ttmp1+1,er3)
  1125.                                                             byteplace(ttmp2+1,eg3)
  1126.                                                             byteplace(ttmp3+1,eb3)
  1127.                                                  IF (i<(finalw-2))
  1128.                                                                 byteplace(ttmp1+2,er4)
  1129.                                                                 byteplace(ttmp2+2,eg4)
  1130.                                                                 byteplace(ttmp3+2,eb4)
  1131.                                                  ENDIF
  1132.                                                         ENDIF
  1133.                                              byteplace(ttmp1,er2)
  1134.                                              byteplace(ttmp2,eg2)
  1135.                                              byteplace(ttmp3,eb2)
  1136.                                          ENDIF
  1137.                                      ENDIF
  1138.                                  ENDIF
  1139.                            ENDIF
  1140.                                     ENDSELECT
  1141.                                 ENDIF
  1142.                                 tmp1:=tmp1+step
  1143.                                 tmp2:=tmp2+step
  1144.                                 tmp3:=tmp3+step
  1145.                             i:=i+step;UNTIL i=stop
  1146.                         ENDFOR
  1147.                     ENDIF
  1148.                     IF (renderham=6) THEN highpen:=63
  1149.                     IF (renderham=8) THEN highpen:=255
  1150.                     IF iinfo
  1151.                         iinfo.source_w:=bmhd.width
  1152.                         iinfo.source_h:=bmhd.height
  1153.                         iinfo.destination_x:=finalx
  1154.                         iinfo.destination_y:=finaly
  1155.                         iinfo.destination_w:=finalw
  1156.                         iinfo.destination_h:=finalh
  1157.                         iinfo.depth:=bmhd.depth
  1158.                         iinfo.highest_pen:=highpen
  1159.                         IF ((renderham=6) OR (renderham=8)) THEN usehighpen:=3
  1160.                         iinfo.blackpen:=FindColor(cmap,0,0,0,usehighpen)
  1161.                         iinfo.whitepen:=FindColor(cmap,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,usehighpen)
  1162.                         iinfo.greypen:=FindColor(cmap,$99999999,$99999999,$99999999,usehighpen)
  1163.                         IF statwindow
  1164.                             iinfo.statwindowx:=stat.centerx-(statx-statwindow.leftedge)
  1165.                             iinfo.statwindowy:=stat.centery-(staty-statwindow.topedge)
  1166.                         ENDIF
  1167.                     ENDIF
  1168.                     IF (gaugestr<>0)
  1169.                         WriteF(gaugestr,100)
  1170.                     ENDIF
  1171.                 ELSE
  1172.                     Raise("MEM")
  1173.                 ENDIF
  1174.             ELSE
  1175.                 Raise("Nodt")
  1176.             ENDIF
  1177.         ELSE
  1178.             Raise("Nodt")
  1179.         ENDIF
  1180.     ELSE
  1181.         Raise("Nodt")
  1182.     ENDIF
  1183. EXCEPT DO
  1184.     res:=exception
  1185.     IF statwindow
  1186.         CloseWindow(statwindow)
  1187.         IF glist
  1188.             FreeGadgets(glist)
  1189.         ENDIF
  1190.         statwindow:=0
  1191.     ENDIF
  1192.     IF gaugeobj THEN DisposeObject(gaugeobj)
  1193.     IF drawinfo THEN FreeScreenDrawInfo(gauge.scr,drawinfo)
  1194.     IF vis THEN FreeVisualInfo(vis)
  1195.     IF obj THEN DisposeDTObject(obj)
  1196.     IF tbm THEN FreeBitMap(tbm)
  1197.     IF redbuf THEN Dispose(redbuf)
  1198.     IF grnbuf THEN Dispose(grnbuf)
  1199.     IF blubuf THEN Dispose(blubuf)
  1200.     IF linebuf THEN Dispose(linebuf)
  1201.     IF grabbuf THEN Dispose(grabbuf)
  1202.     IF trast THEN Dispose(trast)
  1203.     IF dtf THEN Dispose(dtf)
  1204.     IF fri THEN Dispose(fri)
  1205.     IF histo THEN Dispose(histo)
  1206.     IF red24 THEN Dispose(red24)
  1207.     IF grn24 THEN Dispose(grn24)
  1208.     IF blu24 THEN Dispose(blu24)
  1209.     IF gpl THEN Dispose(gpl)
  1210.     IF dtrast THEN Dispose(dtrast)
  1211.     IF gaugeclass THEN Free_gaugeiclass(gaugeclass)
  1212. ENDPROC res
  1213.  
  1214. PROC checklibs()
  1215.     IF ((iffparsebase) AND (utilitybase) AND (datatypesbase) AND (mathbase) AND (gaugeimagebase)) THEN RETURN TRUE
  1216. ENDPROC FALSE        
  1217.  
  1218. PROC checkcancel(window:PTR TO window)
  1219.     DEF mes:PTR TO intuimessage
  1220.     DEF    class
  1221.     DEF retu=FALSE
  1222.     IF window
  1223.         REPEAT
  1224.             IF mes:=Gt_GetIMsg(window.userport)
  1225.                 class:=extractmessage(mes)
  1226.                 IF (class=IDCMP_GADGETUP)
  1227.                     retu:=TRUE
  1228.                 ELSEIF class=IDCMP_REFRESHWINDOW
  1229.                     Gt_BeginRefresh(window)
  1230.                     Gt_EndRefresh(window,TRUE)
  1231.                 ENDIF
  1232.                 Gt_ReplyIMsg(mes)
  1233.             ENDIF
  1234.         UNTIL mes=0
  1235.     ELSE
  1236.         IF CtrlC() THEN retu:=TRUE
  1237.     ENDIF
  1238. ENDPROC retu
  1239.  
  1240. PROC byteplace(loc,error)
  1241.     DEF old
  1242.     old:=Char(loc)
  1243.     old:=old+error
  1244.     IF old<0 THEN old:=0
  1245.     IF old>255 THEN old:=255
  1246.     PutChar(loc,old)
  1247. ENDPROC
  1248.  
  1249. /*PROC rgbint(intval)
  1250.     DEF r,g,b
  1251.     r:=intval AND $F
  1252.     r:=r OR Shl(r,4)
  1253.     g:=Shr((intval AND $F0),4)
  1254.     g:=g OR Shl(g,4)
  1255.     b:=Shr((intval AND $F00),8)
  1256.     b:=b OR Shl(b,4)
  1257. ENDPROC r,g,b*/
  1258.  
  1259. /*PROC rgb2int(r,g,b)
  1260.     DEF int=0
  1261.     int:=(Shr(r,4) OR (Shl(Shr(g,4),4)) OR (Shl(Shr(b,4),8)) )
  1262. ENDPROC int*/
  1263.  
  1264. /*PROC rgbtab(r,g,b)
  1265.     DEF rr
  1266.     rr:=(r+(g*16)+(b*256))*4
  1267. ENDPROC rr*/
  1268.  
  1269. PROC domediancut(redbuf,grnbuf,blubuf,width,height,palette,newcolors,mode=QUANT_MEDIANCUT)
  1270.     DEF chv=0:PTR TO colorhist_item
  1271.     DEF colors=0
  1272.     DEF colormap
  1273.     
  1274.     histopool:=createpool()
  1275.     chv:=computecolorhist(redbuf,grnbuf,blubuf,width,height,MAXCOLORS,{colors})
  1276.     IF chv
  1277. ->        WriteF('\n\nFOUND \d COLORS! -- Choosing \d colors...\n\n',colors,newcolors)
  1278.  
  1279.         colormap:=mediancut(chv,colors,width*height,newcolors,mode)
  1280.         
  1281.         Dispose(chv)
  1282.     ENDIF
  1283. ENDPROC colormap
  1284.  
  1285. PROC mediancut(chv,colors,sum,newcolors,mode=QUANT_MEDIANCUT)
  1286.     DEF colormap=0,bv=0
  1287.     DEF boxes,bi,i,i2,realsplit,bigbox,movebox,tmp1,tmp2,score
  1288.     DEF box:PTR TO box,chi:PTR TO colorhist_item
  1289.     DEF indx,clrs,sm,v,halfcolor,halfsum,lowersum
  1290.     DEF r,g,b,rsum,gsum,bsum
  1291.     DEF rl,gl,bl
  1292.     DEF f_0_299,f_0_587,f_0_114
  1293.     DEF colo
  1294.     bv:=New((SIZEOF box*newcolors)+100)
  1295.     f_0_299:=SpDiv(SpFlt(1000),SpFlt(299))
  1296.     f_0_587:=SpDiv(SpFlt(1000),SpFlt(587))
  1297.     f_0_114:=SpDiv(SpFlt(1000),SpFlt(114))
  1298.     IF (bv)
  1299.         colormap:=New((SIZEOF colorhist_item*newcolors)+100)
  1300.         IF (colormap)
  1301.             FOR i:=0 TO (newcolors-1)
  1302.                 PutLong(colormap+(i*SIZEOF colorhist_item),0)
  1303.                 PutLong(colormap+(i*SIZEOF colorhist_item)+4,0)
  1304.             ENDFOR
  1305.             box:=bv
  1306.             box.ind:=0
  1307.             box.colors:=colors
  1308.             box.sum:=sum
  1309.             boxes:=1
  1310.             sizebox(box,chv)
  1311.             WHILE (boxes<newcolors)
  1312.  
  1313.                 IF checkcancel(statwindow)
  1314.                     IF chv THEN Dispose(chv)
  1315.                     IF bv THEN Dispose(bv)
  1316.                     IF colormap THEN Dispose(colormap)
  1317.                     Raise("canc")
  1318.                 ENDIF
  1319.                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,boxes,newcolors,stat.quant_string,drawinfo)
  1320.  
  1321.                 FOR bi:=0 TO (boxes-1)
  1322.                     box:=bv+(bi*SIZEOF box)
  1323.                     IF box.colors>=2 THEN JUMP break2
  1324.                 ENDFOR
  1325.                 JUMP break3
  1326. break2:
  1327.                 indx:=box.ind
  1328.                 clrs:=box.colors
  1329.                 sm:=box.sum
  1330.  
  1331.                 SELECT QUANT_END OF mode
  1332. /*
  1333.                 CASE QUANT_MEDIANCUT
  1334.                     rl:=SpMul(SpFlt(box.redw),f_0_299)
  1335.                     gl:=SpMul(SpFlt(box.grnw),f_0_587)
  1336.                     bl:=SpMul(SpFlt(box.bluw),f_0_114)
  1337. */
  1338.                 CASE QUANT_MEDIANCUT4,QUANT_MEDIANCUT2,QUANT_MEDIANCUT3
  1339.                     rl:=SpFlt(box.redw)
  1340.                     gl:=SpFlt(box.grnw)
  1341.                     bl:=SpFlt(box.bluw)
  1342.                 DEFAULT
  1343.                     rl:=SpMul(SpFlt(18),SpFlt(box.redw))
  1344.                     gl:=SpMul(SpFlt(20),SpFlt(box.grnw))
  1345.                     bl:=SpMul(SpFlt(17),SpFlt(box.bluw))
  1346.                 ENDSELECT
  1347.  
  1348.                 IF ((SpCmp(gl,rl)>=0) AND (SpCmp(gl,bl)>=0))
  1349.                     qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF00)
  1350.                     v:=1
  1351.                 ELSE
  1352.                     IF (SpCmp(rl,bl)>=0)
  1353.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF0000)
  1354.                         v:=0
  1355.                     ELSE
  1356.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF)
  1357.                         v:=2
  1358.                     ENDIF
  1359.                 ENDIF
  1360.                 chi:=chv+(indx*SIZEOF colorhist_item)
  1361.                 lowersum:=chi.value
  1362.                 halfsum:=(sm/2)
  1363.                 i:=1
  1364.                 WHILE (i<(clrs-1))
  1365.                     IF (lowersum>=halfsum)
  1366.                         SELECT v
  1367.                         CASE 0
  1368.                             gsum:=PPM_GETR(chi.color)
  1369.                             IF gsum>rsum THEN JUMP break4
  1370.                         CASE 1
  1371.                             gsum:=PPM_GETG(chi.color)
  1372.                             IF gsum>rsum THEN JUMP break4
  1373.                         CASE 2
  1374.                             gsum:=PPM_GETB(chi.color)
  1375.                             IF gsum>rsum THEN JUMP break4
  1376.                         ENDSELECT
  1377.                     ENDIF
  1378.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1379.                     IF (lowersum<halfsum)
  1380.                         SELECT v
  1381.                         CASE 0;rsum:=PPM_GETR(chi.color)
  1382.                         CASE 1;rsum:=PPM_GETG(chi.color)
  1383.                         CASE 2;rsum:=PPM_GETB(chi.color)
  1384.                         ENDSELECT
  1385.                     ENDIF
  1386.                     lowersum:=lowersum+(chi.value)
  1387.                 i:=i+1;ENDWHILE
  1388.  
  1389. ->WriteF('\n\nOUCH! GOT ALL COLORS!')
  1390.  
  1391. break4:
  1392.  
  1393.                 i2:=1
  1394.                 WHILE (i2<(clrs-1))
  1395.                     SELECT v
  1396.                     CASE 0;IF (PPM_GETR(chi.color)>(box.red0+(box.redw/2))) THEN JUMP break8
  1397.                     CASE 1;IF (PPM_GETG(chi.color)>(box.grn0+(box.grnw/2))) THEN JUMP break8
  1398.                     CASE 2;IF (PPM_GETB(chi.color)>(box.blu0+(box.bluw/2))) THEN JUMP break8
  1399.                     ENDSELECT            
  1400.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1401.                 i2:=i2+1;ENDWHILE
  1402.  
  1403. ->WriteF('\n\nOUCH! GOT ALL COLORS!')
  1404.  
  1405. break8:
  1406.  
  1407.                 SELECT QUANT_END OF mode
  1408.                 CASE QUANT_MEDIANCUT;realsplit:=i
  1409.                 CASE QUANT_MEDIANCUT5;realsplit:=i2
  1410.                 DEFAULT;realsplit:=limit((i+i2)/2,1,(clrs-1))
  1411.                 ENDSELECT
  1412. ->WriteF('\nSplit at \d AND \d,  really at \d',i,i2,realsplit)
  1413.  
  1414.                 lowersum:=0
  1415.                 FOR i:=0 TO realsplit
  1416.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1417.                     lowersum:=lowersum+chi.value
  1418.                 ENDFOR
  1419.  
  1420.                 lowersum:=limit(lowersum,0,sm-1)
  1421.                 box:=bv+(bi*SIZEOF box)
  1422.                 box.colors:=realsplit
  1423.                 box.sum:=lowersum
  1424.                 sizebox(box,chv)
  1425.                 box:=bv+(boxes*SIZEOF box)
  1426.                 box.ind:=indx+realsplit
  1427.                 box.colors:=clrs-realsplit
  1428.                 box.sum:=sm-lowersum
  1429.                 sizebox(box,chv)
  1430.                 boxes:=boxes+1
  1431.  
  1432.                 bigbox:=0;movebox:=0
  1433.                 box:=(bv-SIZEOF box)
  1434.  
  1435. /*  Find the largest box to split, and move it to position ZERO. */
  1436.  
  1437.                 FOR i:=0 TO boxes-1
  1438.                     box:=(box+SIZEOF box)
  1439.                     IF (box.colors>1)
  1440.                         SELECT QUANT_END OF mode
  1441.                         CASE QUANT_MEDIANCUT
  1442.                             IF (box.redw)>bigbox
  1443.                                 bigbox:=box.redw
  1444.                                 movebox:=i
  1445.                             ENDIF
  1446.                             IF (box.grnw)>bigbox
  1447.                                 bigbox:=box.grnw
  1448.                                 movebox:=i
  1449.                             ENDIF
  1450.                             IF (box.bluw)>bigbox
  1451.                                 bigbox:=box.bluw
  1452.                                 movebox:=i
  1453.                             ENDIF
  1454.                         CASE QUANT_MEDIANCUT2
  1455.                             score:=(((box.redw*box.redw))+((box.grnw*box.grnw))+(box.bluw*box.bluw))
  1456.                             IF score>bigbox;movebox:=i;bigbox:=score;ENDIF
  1457.                         CASE QUANT_MEDIANCUT3
  1458.                             IF (boxes<(newcolors/3))
  1459.                                 IF (box.colors>bigbox);movebox:=i;bigbox:=box.colors;ENDIF
  1460.                             ELSE
  1461.                                 IF (boxes<((newcolors*2)/3))
  1462.                                     score:=((box.redw)*(box.grnw)*(box.bluw))
  1463.                                     IF (score>bigbox);movebox:=i;bigbox:=score;ENDIF
  1464.                                 ELSE
  1465.                                     IF (box.redw)>bigbox
  1466.                                         bigbox:=box.redw
  1467.                                         movebox:=i
  1468.                                     ENDIF
  1469.                                     IF (box.grnw)>bigbox
  1470.                                         bigbox:=box.grnw
  1471.                                         movebox:=i
  1472.                                     ENDIF
  1473.                                     IF (box.bluw)>bigbox
  1474.                                         bigbox:=box.bluw
  1475.                                         movebox:=i
  1476.                                     ENDIF
  1477.                                 ENDIF
  1478.                             ENDIF
  1479.                         CASE QUANT_MEDIANCUT4
  1480.                             IF (boxes*2<=newcolors)
  1481.                                 IF (box.colors>bigbox)
  1482.                                     bigbox:=box.colors
  1483.                                     movebox:=i
  1484.                                 ENDIF
  1485.                             ELSE
  1486.                                 IF (box.redw*box.grnw*box.bluw)>bigbox
  1487.                                     bigbox:=(box.redw*box.grnw*box.bluw)
  1488.                                     movebox:=i
  1489.                                 ENDIF
  1490.                             ENDIF
  1491.                         CASE QUANT_MEDIANCUT5
  1492.                             IF (((box.redw*box.colors)>bigbox))
  1493.                                 bigbox:=box.redw*box.colors
  1494.                                 movebox:=i
  1495.                             ENDIF
  1496.                             IF (((box.grnw*box.colors)>bigbox))
  1497.                                 bigbox:=box.grnw*box.colors
  1498.                                 movebox:=i
  1499.                             ENDIF
  1500.                             IF (((box.bluw*box.colors)>bigbox))
  1501.                                 bigbox:=box.bluw*box.colors
  1502.                                 movebox:=i
  1503.                             ENDIF
  1504.                         CASE QUANT_MEDIANCUT6
  1505.                             IF (((box.redw*box.colors*box.sum)>bigbox))
  1506.                                 bigbox:=box.redw*box.colors*box.sum
  1507.                                 movebox:=i
  1508.                             ENDIF
  1509.                             IF (((box.grnw*box.colors*box.sum)>bigbox))
  1510.                                 bigbox:=box.grnw*box.colors*box.sum
  1511.                                 movebox:=i
  1512.                             ENDIF
  1513.                             IF (((box.bluw*box.colors*box.sum)>bigbox))
  1514.                                 bigbox:=box.bluw*box.colors*box.sum
  1515.                                 movebox:=i
  1516.                             ENDIF
  1517.                         CASE QUANT_MEDIANCUT7
  1518.                             IF (((box.redw*box.sum)>bigbox))
  1519.                                 bigbox:=box.redw*box.colors*box.sum
  1520.                                 movebox:=i
  1521.                             ENDIF
  1522.                             IF (((box.grnw*box.sum)>bigbox))
  1523.                                 bigbox:=box.grnw*box.colors*box.sum
  1524.                                 movebox:=i
  1525.                             ENDIF
  1526.                             IF (((box.bluw*box.sum)>bigbox))
  1527.                                 bigbox:=box.bluw*box.colors*box.sum
  1528.                                 movebox:=i
  1529.                             ENDIF
  1530.                         ENDSELECT
  1531.                     ENDIF
  1532.                 ENDFOR
  1533.                 swapboxes(bv,bv+(movebox*SIZEOF box))
  1534. /*
  1535. FOR i:=0 TO boxes-1
  1536.     box:=bv+(i*SIZEOF box)
  1537.     WriteF('\n#\d[3] (\d[4] s\d[4] c\d[4]) (\d[3],\d[3])\d[3] (\d[3],\d[3])\d[3] (\d[3],\d[3])\d[3]',i,box.ind,box.sum,box.colors,box.red0,box.red1,box.redw,box.grn0,box.grn1,box.grnw,box.blu0,box.blu1,box.bluw)
  1538. ENDFOR
  1539. */
  1540.             ENDWHILE
  1541. break3:
  1542.             FOR bi:=0 TO (boxes-1)
  1543.                 box:=bv+(bi*SIZEOF box)
  1544.                 indx:=box.ind
  1545.                 clrs:=box.colors
  1546.                 SELECT QUANT_END OF mode
  1547.                 CASE QUANT_MEDIANCUT
  1548.                     r:=0;g:=0;b:=0;sum:=0
  1549.                     FOR i:=0 TO (clrs-1)
  1550.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1551.                         colo:=chi.color
  1552.                         r:=r+((PPM_GETR(colo)))
  1553.                         g:=g+((PPM_GETG(colo)))
  1554.                         b:=b+((PPM_GETB(colo)))
  1555.                         sum:=sum+1
  1556.                     ENDFOR
  1557.                     r:=limit(r/sum,0,255)
  1558.                     g:=limit(g/sum,0,255)
  1559.                     b:=limit(b/sum,0,255)
  1560.                 CASE QUANT_MEDIANCUT2,QUANT_MEDIANCUT3
  1561.                     r:=SpFlt(0);g:=SpFlt(0);b:=SpFlt(0);sum:=SpFlt(0)
  1562.                     FOR i:=0 TO (clrs-1)
  1563.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1564.                         colo:=chi.color
  1565.                         tmp1:=SpFlt(chi.value)
  1566.                         r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo)),tmp1))
  1567.                         g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1))
  1568.                         b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo)),tmp1))
  1569.                         sum:=SpAdd(sum,tmp1)
  1570.                     ENDFOR
  1571.                     IF SpFix(sum)=0 THEN sum:=SpFlt(1)
  1572.                     r:=limit(SpFix(SpDiv(sum,r)),0,255)
  1573.                     g:=limit(SpFix(SpDiv(sum,g)),0,255)
  1574.                     b:=limit(SpFix(SpDiv(sum,b)),0,255)
  1575.                 DEFAULT
  1576.                     r:=SpFlt(0);g:=SpFlt(0);b:=SpFlt(0)
  1577.                     rsum:=SpFlt(0);gsum:=SpFlt(0);bsum:=SpFlt(0)
  1578.                     FOR i:=0 TO (clrs-1)
  1579.                         chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1580.                         colo:=chi.color
  1581.                         tmp1:=SpFlt(chi.value)
  1582.                         r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo) OR 1),tmp1));rsum:=SpAdd(rsum,tmp1)
  1583.                         g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1));gsum:=SpAdd(gsum,tmp1)
  1584.                         b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo) OR 4),tmp1));bsum:=SpAdd(bsum,tmp1)
  1585. ->                        IF mode=QUANT_MEDIANCUT2
  1586.                             IF PPM_GETR(colo)>63 AND PPM_GETR(colo)<196
  1587.                                 r:=SpAdd(r,SpMul(SpFlt(PPM_GETR(colo) OR $1),tmp1));rsum:=SpAdd(rsum,tmp1)
  1588.                             ENDIF
  1589.                             IF PPM_GETG(colo)>63 AND PPM_GETG(colo)<196
  1590.                                 g:=SpAdd(g,SpMul(SpFlt(PPM_GETG(colo)),tmp1));gsum:=SpAdd(gsum,tmp1)
  1591.                             ENDIF
  1592.                             IF PPM_GETB(colo)>63 AND PPM_GETB(colo)<196
  1593.                                 b:=SpAdd(b,SpMul(SpFlt(PPM_GETB(colo) OR 4),tmp1));bsum:=SpAdd(bsum,tmp1)
  1594.                             ENDIF
  1595. ->                        ENDIF
  1596.                     ENDFOR
  1597.                     IF SpFix(rsum)=0 THEN rsum:=SpFlt(1)
  1598.                     IF SpFix(gsum)=0 THEN gsum:=SpFlt(1)
  1599.                     IF SpFix(bsum)=0 THEN bsum:=SpFlt(1)
  1600.                     r:=limit(SpFix(SpDiv(rsum,r)),0,255)
  1601.                     g:=limit(SpFix(SpDiv(gsum,g)),0,255)
  1602.                     b:=limit(SpFix(SpDiv(bsum,b)),0,255)
  1603.                 ENDSELECT
  1604.                 chi:=colormap+(bi*SIZEOF colorhist_item)
  1605.                 chi.color:=PPM_ASSIGN(r,g,b)
  1606.             ENDFOR
  1607.         ENDIF
  1608.         Dispose(bv)
  1609.     ENDIF
  1610. ENDPROC colormap
  1611.  
  1612. PROC swapboxes(box1:PTR TO box,box2:PTR TO box)
  1613.     DEF tmp
  1614.     tmp:=box1.ind;        box1.ind:=box2.ind;                box2.ind:=tmp
  1615.     tmp:=box1.colors;    box1.colors:=box2.colors;    box2.colors:=tmp
  1616.     tmp:=box1.sum;        box1.sum:=box2.sum;                box2.sum:=tmp
  1617.     tmp:=box1.redw;        box1.redw:=box2.redw;            box2.redw:=tmp
  1618.     tmp:=box1.grnw;        box1.grnw:=box2.grnw;            box2.grnw:=tmp
  1619.     tmp:=box1.bluw;        box1.bluw:=box2.bluw;            box2.bluw:=tmp
  1620.     tmp:=box1.red0;        box1.red0:=box2.red0;            box2.red0:=tmp
  1621.     tmp:=box1.grn0;        box1.grn0:=box2.grn0;            box2.grn0:=tmp
  1622.     tmp:=box1.blu0;        box1.blu0:=box2.blu0;            box2.blu0:=tmp
  1623.     tmp:=box1.red1;        box1.red1:=box2.red1;            box2.red1:=tmp
  1624.     tmp:=box1.grn1;        box1.grn1:=box2.grn1;            box2.grn1:=tmp
  1625.     tmp:=box1.blu1;        box1.blu1:=box2.blu1;            box2.blu1:=tmp
  1626. ENDPROC
  1627.  
  1628. PROC computecolorhist(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1629.     DEF cht=0
  1630.     DEF chv=0
  1631.     cht:=computecolorhash(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1632.     IF cht
  1633.         chv:=colorhashtocolorhist(cht,maxcolors)
  1634.         freecolorhash(cht)
  1635.         RETURN chv
  1636.     ELSE
  1637.         RETURN 0
  1638.     ENDIF
  1639. ENDPROC
  1640.  
  1641. PROC computecolorhash(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1642.     DEF cht=0
  1643.     DEF pP=0
  1644.     DEF chl=0:PTR TO colorhist_list_item
  1645.     DEF col,row,hash,ccoolloorr
  1646.     cht:=alloccolorhash()
  1647.     IF cht
  1648.         PutLong(colorsP,0)
  1649.         row:=0
  1650.         REPEAT
  1651.             IF checkcancel(statwindow)
  1652.                 freecolorhash(cht)
  1653.                 Raise("canc")
  1654.             ENDIF
  1655.             IF ((row/4)=((row+3)/4)) 
  1656.                 IF gaugeobj THEN fuelgauge(statwindow.rport,gaugeobj,row,rows-1,stat.histogram_string,drawinfo)
  1657.             ENDIF
  1658.             col:=0
  1659.             REPEAT
  1660.                 ccoolloorr:=((PPM_PUTR(Char(redbuf+pP)) OR PPM_PUTG(Char(grnbuf+pP)) OR PPM_PUTB(Char(blubuf+pP))) AND $FCFEF8)  -> Give RED 6 BITS, GRN 7 BITS, and BLU 5 BITS...this helps improve clustering, and to keep the number of unique colors below 32768 !
  1661.                 hash:=HASHPIXEL(ccoolloorr)
  1662.                 chl:=Long(cht+(hash*4))
  1663.                 WHILE (chl<>0)
  1664.                     IF (chl.ch.color=ccoolloorr)
  1665.                         JUMP break
  1666.                     ENDIF
  1667.                     chl:=chl.next
  1668.                 ENDWHILE
  1669. break:
  1670.                 IF (chl<>0)
  1671.                     chl.ch.value:=(chl.ch.value+1)
  1672.                 ELSE
  1673.                     PutLong(colorsP,Long(colorsP)+1)
  1674.                     IF Long(colorsP)>maxcolors
  1675.                         freecolorhash(cht)
  1676.                         RETURN 0
  1677.                     ENDIF
  1678. ->                    chl:=New(SIZEOF colorhist_list_item)
  1679.                     chl:=alloc(histopool,SIZEOF colorhist_list_item)
  1680.                     IF chl
  1681.                         chl.ch.color:=ccoolloorr
  1682.                         chl.ch.value:=1
  1683.                         chl.next:=Long(cht+(hash*4))
  1684.                         PutLong((cht+(hash*4)),chl)
  1685.                     ENDIF
  1686.                 ENDIF
  1687.             col:=col+1;pP:=pP+1;UNTIL col=cols
  1688.         row:=row+1;UNTIL row=rows
  1689.     ENDIF
  1690. ENDPROC cht
  1691.  
  1692. PROC alloccolorhash()
  1693.     DEF cht=0
  1694.     cht:=New((HASH_SIZE*4)+20)
  1695. ENDPROC cht
  1696.  
  1697. PROC colorhashtocolorhist(cht,maxcolors)
  1698.     DEF chv=0:PTR TO colorhist_item
  1699.     DEF chl=0:PTR TO colorhist_list_item
  1700.     DEF i,j
  1701.     chv:=New((maxcolors*SIZEOF colorhist_item)+20)
  1702.     j:=0
  1703.     FOR i:=0 TO (HASH_SIZE-1)
  1704.         chl:=Long(cht+(i*4))
  1705.         WHILE (chl<>0)
  1706.             PutLong(chv+(j*SIZEOF colorhist_item),chl.ch.color)
  1707.             PutLong(chv+4+(j*SIZEOF colorhist_item),chl.ch.value)
  1708.             j:=j+1
  1709.             chl:=chl.next
  1710.         ENDWHILE
  1711.     ENDFOR
  1712. ENDPROC chv
  1713.  
  1714. PROC freecolorhash(cht)
  1715.     DEF i
  1716.     DEF chl:PTR TO colorhist_list_item
  1717.     DEF chlnext
  1718.     i:=0
  1719.     deletepool(histopool)
  1720.     Dispose(cht)
  1721. ENDPROC 0
  1722.  
  1723. PROC qsort(chv,l,r,and)
  1724.     DEF i,j,x,m1,m2
  1725.     x:=((Long(chv+((Shr(l+r,1))*SIZEOF colorhist_item))) AND and)
  1726.     i:=l
  1727.     j:=r
  1728.     REPEAT
  1729.         WHILE (((Long(chv+(i++*SIZEOF colorhist_item))) AND and) < x)
  1730.         ENDWHILE
  1731.         WHILE (x<((Long(chv+(j*SIZEOF colorhist_item))) AND and))
  1732.             j:=j-1
  1733.         ENDWHILE
  1734.         IF (i-- <=j)
  1735.             m1:=chv+(j*SIZEOF colorhist_item)
  1736.             m2:=chv+(i*SIZEOF colorhist_item)
  1737.             MOVE.L    m1,A0
  1738.             MOVE.L    m2,A1
  1739.  
  1740.             MOVE.L    (A0),D0
  1741.             MOVE.L    (A1),(A0)+
  1742.             MOVE.L    D0,(A1)+
  1743.             MOVE.L    (A0),D0
  1744.             MOVE.L    (A1),(A0)
  1745.             MOVE.L    D0,(A1)
  1746.             i:=i+1
  1747.             DEC j
  1748.         ENDIF
  1749.     UNTIL i>j
  1750.     IF l<j THEN qsort(chv,l,j,and)
  1751.     IF i<r THEN qsort(chv,i,r,and)
  1752. ENDPROC
  1753.  
  1754. PROC doexchange(cmap,pen,r,g,b,uhp)
  1755.     DEF newpen
  1756.     newpen:=findcolorbytes(cmap,r,g,b,uhp)
  1757.     exchangecolorcmap(cmap,pen,newpen)
  1758. ENDPROC
  1759.  
  1760. PROC sizebox(box:PTR TO box,chv)
  1761.     DEF i,ptr:PTR TO colorhist_item
  1762.     DEF mr=255,mg=255,mb=255,xr=0,xg=0,xb=0
  1763.     DEF color,r,g,b
  1764.     ptr:=chv+(box.ind*SIZEOF colorhist_item)
  1765.     FOR i:=0 TO box.colors-1
  1766.         color:=ptr.color
  1767.         MOVE.L    color,D0
  1768.         MOVE.L    D0,D1
  1769.         AND.L        #$FF,D1
  1770.         MOVE.L    D1,b
  1771.         LSR.L        #8,D0
  1772.         MOVE.L    D0,D1
  1773.         AND.L        #$FF,D1
  1774.         MOVE.L    D1,g
  1775.         LSR.L        #8,D0
  1776.         MOVE.L    D0,D1
  1777.         AND.L        #$FF,D1
  1778.         MOVE.L    D1,r
  1779.         IF (r<mr) THEN mr:=r
  1780.         IF (g<mg) THEN mg:=g
  1781.         IF (b<mb) THEN mb:=b
  1782.         IF (r>xr) THEN xr:=r
  1783.         IF (g>xg) THEN xg:=g
  1784.         IF (b>xb) THEN xb:=b
  1785.         ptr:=ptr+SIZEOF colorhist_item
  1786.     ENDFOR
  1787.     box.redw:=xr-mr
  1788.     box.grnw:=xg-mg
  1789.     box.bluw:=xb-mb
  1790.     box.red0:=mr
  1791.     box.grn0:=mg
  1792.     box.blu0:=mb
  1793.     box.red1:=xr
  1794.     box.grn1:=xg
  1795.     box.blu1:=xb
  1796. ->    WriteF('\n (\d,\d ---\d) (\d,\d ---\d) (\d,\d ---\d)',box.red0,box.red1,box.redw,box.grn0,box.grn1,box.grnw,box.blu0,box.blu1,box.bluw)
  1797. ENDPROC
  1798.  
  1799. PROC mergesize(sizestruct:PTR TO sizestruct,pixw,pixh,redbuf,grnbuf,blubuf,bufw,bufh)
  1800.     DEF cursx,cursy
  1801.     DEF charptr,i,t,x,y,w=0,h=0,tw=0,th=0,ii,tt
  1802.     DEF sizestr[100]:STRING
  1803.     DEF str[10]:STRING
  1804.     DEF mergebuf,font,offx
  1805.     DEF br,bg,bb,p
  1806.     mergebuf:=New(8000)
  1807.     StringF(sizestr,'\dx\d',pixw,pixh)
  1808.     
  1809.     FOR i:=0 TO (StrLen(sizestr)-1)
  1810.         w,h:=getfontwh(sizestruct.font,Char(sizestr+i))
  1811.         tw:=tw+w
  1812.         th:=bigger(th,h)
  1813.     ENDFOR
  1814.     IF sizestruct.x=-1 THEN sizestruct.x:=(bufw/2)-(tw/2)
  1815.     IF sizestruct.y=-1 THEN sizestruct.y:=(bufh-th-2)
  1816.     offx:=1;tw:=tw+2;th:=th+2
  1817.     FOR i:=0 TO (StrLen(sizestr)-1)
  1818.         w,h,font:=getfontwh(sizestruct.font,Char(sizestr+i))
  1819.         FOR tt:=0 TO (h-1)
  1820.             FOR ii:=0 TO (w-1)
  1821.                 PutChar(mergebuf+ii+offx+((tt+1)*tw),Char(font+ii+(tt*w)))
  1822.             ENDFOR
  1823.         ENDFOR
  1824.         offx:=offx+w
  1825.     ENDFOR
  1826.     FOR ii:=0 TO tw-1
  1827.         FOR tt:=0 TO th-1
  1828.             p:=sizestruct.x+ii+(tt*bufw)+(sizestruct.y*bufw)
  1829.             IF p>=0
  1830.                 IF (p<(bufw*bufh))
  1831.                     br:=Char(redbuf+p)
  1832.                     bg:=Char(grnbuf+p)
  1833.                     bb:=Char(blubuf+p)
  1834.                     i:=Char(mergebuf+ii+(tt*tw))
  1835.                     IF sizestruct.type=TEXT_SHADOW
  1836.                         br:=limit(((br+i)/2),0,255)
  1837.                         bg:=limit(((bg+i)/2),0,255)
  1838.                         bb:=limit(((bb+i)/2),0,255)
  1839.                     ELSE
  1840.                         br:=i
  1841.                         bg:=i
  1842.                         bb:=i
  1843.                     ENDIF
  1844.                     PutChar(redbuf+p,br)
  1845.                     PutChar(grnbuf+p,bg)
  1846.                     PutChar(blubuf+p,bb)
  1847.                 ENDIF
  1848.             ENDIF
  1849.         ENDFOR
  1850.     ENDFOR
  1851. ENDPROC
  1852.  
  1853. PROC getfontwh(font,chr)
  1854.     DEF fw,fh,i
  1855.     IF ((chr<"0") OR (chr>"9")) THEN chr:=("9"+1)
  1856.     IF chr>"0"
  1857.         FOR i:=0 TO ((chr-"0")-1)
  1858.             fw:=Char(font);fh:=Char(font+1)
  1859.             font:=(font+(fw*fh)+2)
  1860.         ENDFOR
  1861.     ENDIF
  1862.     fw:=Char(font);fh:=Char(font+1)
  1863.     font:=font+2
  1864. ENDPROC fw,fh,font
  1865.  
  1866. PROC fuelgauge(rport,gaugeobj,level,top,string,drawinfo)
  1867.     SetAttrsA(gaugeobj,
  1868.          [IA_DATA,string,
  1869.             GAUGEIA_TOP,top,
  1870.             GAUGEIA_CURLEVEL,level,
  1871.             GAUGEIA_BOTTOM,0,
  1872.             TAG_END])
  1873.     DrawImageState(rport,gaugeobj,0,0,IDS_NORMAL,drawinfo)
  1874. ENDPROC
  1875.